/*
 * tab_watch.cpp
 *
 *  Created on: 13.06.2013
 *      Author: SpirTanol
 */

#include "ui/tab_watch.h"
#include "ui/table_protocol.h"
#include "ui/watch_plot.h"
#include "ui/main_window.h"
#include "packets/watch_data_packet.h"
#include "packets/config_packet.h"
#include "device/device_info.h"
#include "global.h"
#include "events/data_event.h"
#include "ui/temp_plot.h"
#include "app_config.h"

// QT
#include <QGridLayout>
#include <QLabel>
#include <QPushButton>
#include <QProgressBar>
#include <QSpacerItem>
#include <QDateTime>
#include <QBoxLayout>
#include <QMessageBox>
//======================================================================================
TabWatch::TabWatch(MainWindow *mainWindow, QVector<ProtocolEvent*> *protocol, QWidget *parent) : QSplitter(parent), oMainWindow(mainWindow)
{
	setOrientation(Qt::Vertical);

	QWidget *top = new QWidget();
	addWidget(top);

	QGridLayout *l = new QGridLayout(top);

	QWidget *detectPanel = new QWidget();
	detectPanel->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
	detectPanel->setStyleSheet("QLabel { border:1px solid #000000; } ");
	l->addWidget(detectPanel, 0, 0);

	QGridLayout *ldetect = new QGridLayout(detectPanel);

	int row = 0;

	oLabelCrash = new QLabel();
	oLabelCrash->setAlignment(Qt::AlignCenter);
	oLabelCrash->setFixedHeight(40);
	oLabelCrash->setWordWrap(true);
	ldetect->addWidget(oLabelCrash, row++, 0, 1, 3);

	oLabelRT100State = new QLabel();
	oLabelRT100State->setAlignment(Qt::AlignCenter);
	oLabelRT100State->setFixedHeight(40);
	oLabelRT100State->setWordWrap(true);
	ldetect->addWidget(oLabelRT100State, row++, 0, 1, 3);

	oLabelTemp = new QLabel();
	oLabelTemp->setAlignment(Qt::AlignCenter);
	oLabelTemp->setFixedHeight(40);
	ldetect->addWidget(oLabelTemp, row, 0, 1, 2);

	oLabelEngine = new QLabel();
	oLabelEngine->setAlignment(Qt::AlignCenter);
	oLabelEngine->setFixedHeight(40);
	ldetect->addWidget(oLabelEngine, row++, 2);

	oBtnForward = new QPushButton(trUtf8("Вперёд"));
	oBtnForward->setFixedHeight(40);
	ldetect->addWidget(oBtnForward, row, 0);
	connect(oBtnForward, SIGNAL(clicked()), this, SLOT(onBtnEngineCommandClicked()));

	oBtnBack = new QPushButton(trUtf8("Назад"));
	oBtnBack->setFixedHeight(40);
	ldetect->addWidget(oBtnBack, row, 1);
	connect(oBtnBack, SIGNAL(clicked()), this, SLOT(onBtnEngineCommandClicked()));

	oBtnStop = new QPushButton(trUtf8("Стоп"));
	oBtnStop->setFixedHeight(40);
	ldetect->addWidget(oBtnStop, row++, 2);
	connect(oBtnStop, SIGNAL(clicked()), this, SLOT(onBtnEngineCommandClicked()));

	QGridLayout *sub = new QGridLayout();
	ldetect->addLayout(sub, row++, 0, 1, 3);

	oLabelIn1 = new QLabel(trUtf8("ВХОД 1"));
	oLabelIn1->setAlignment(Qt::AlignCenter);
	oLabelIn1->setFixedHeight(40);
	sub->addWidget(oLabelIn1, 0, 0);

	oLabelPowerOut = new QLabel(trUtf8("СИЛОВОЙ ВЫХОД"));
	oLabelPowerOut->setAlignment(Qt::AlignCenter);
	oLabelPowerOut->setFixedHeight(40);
	sub->addWidget(oLabelPowerOut, 0, 1, 1, 2);

	oLabelIn2 = new QLabel(trUtf8("ВХОД 2"));
	oLabelIn2->setAlignment(Qt::AlignCenter);
	oLabelIn2->setFixedHeight(40);
	sub->addWidget(oLabelIn2, 1, 0);

	oLabelAppendOut = new QLabel(trUtf8("ДОП. ВЫХОД"));
	oLabelAppendOut->setAlignment(Qt::AlignCenter);
	oLabelAppendOut->setFixedHeight(40);
	sub->addWidget(oLabelAppendOut, 1, 1);

	oBtnAppendOut = new QPushButton(trUtf8("Доп. выход\nвыкл."));
	oBtnAppendOut->setFixedHeight(40);
	sub->addWidget(oBtnAppendOut, 1, 2);
	connect(oBtnAppendOut, SIGNAL(clicked()), this, SLOT(onBtnAppendOutClicked()));

	l->addItem(new QSpacerItem(0, 0, QSizePolicy::Preferred, QSizePolicy::Expanding), 1, 0);

	QGridLayout* l2 = new QGridLayout();
	l->addLayout(l2, 2, 0);

	oLabelWorkTime = new QLabel(trUtf8("Наработка двигателя:"));
	l2->addWidget(oLabelWorkTime);

	oLabelStartCounter = new QLabel(trUtf8("Количество пусков двигателя: 0"));
	l2->addWidget(oLabelStartCounter);

	oLabelTime = new QLabel(trUtf8("Время УЗД"));
	oLabelTime->setAlignment(Qt::AlignCenter);
	oLabelTime->setFixedHeight(40);
	oLabelTime->setStyleSheet("border:1px solid #000000;");
	l2->addWidget(oLabelTime);

	QBoxLayout* right = new QBoxLayout(QBoxLayout::TopToBottom);
	l->addLayout(right, 0, 1, l->rowCount(), 1);

	oWatchPlot = new WatchPlot();
	right->addWidget(oWatchPlot);

	oTempPlot = new TempPlot();
	right->addWidget(oTempPlot);

	oWatchPlot->setMinimumHeight(220);
	oTempPlot->setMinimumHeight(220);

	oTableProtocol = new TableProtocol(protocol);
	addWidget(oTableProtocol);

	setPlotInterval(AppConfig::i()->interval());
}

TabWatch::~TabWatch()
{

}
//======================================================================================
void TabWatch::updateData(const WatchDataPacket *data)
{
	extern int gDeviceVersion;
	extern const QString cgGreenColor;
	extern const QString cgRedColor;
	extern const QString cgOrangeColor;
	extern const QString cgDefColor;

	if (data->crashCode() == 0)
	{
		oLabelCrash->setText(trUtf8("АВАРИЙ НЕТ"));
		oLabelCrash->setStyleSheet(cgGreenColor);
	}
	else
	{
		oLabelCrash->setText(crashText(data->crashCode()));
		oLabelCrash->setStyleSheet(cgRedColor);
	}

	QString text;
	if (oInput1F == 1)
		oLabelIn1->setStyleSheet(data->inputState(0) ? cgRedColor : "");
	else
		oLabelIn1->setStyleSheet(data->inputState(0) ? cgOrangeColor : "");

	if (oInput2F == 5)
	{
		switch (data->wetState())
		{
		case 0:
			text = trUtf8("ОБРЫВ");
			break;
		case 1:
			text = trUtf8("НОРМА");
			break;
		case 2:
			text = trUtf8("ВОДА");
			break;
		}
		oLabelIn2->setText(trUtf8("ВЛАЖНОСТЬ\n") + text);
		if (oWetProtect)
			oLabelIn2->setStyleSheet(data->inputState(1) ? cgGreenColor : cgRedColor);
		else
			oLabelIn2->setStyleSheet("");
	}
	else
	{
		oLabelIn2->setText(trUtf8("ВХОД 2"));
		if (oInput2F == 1)
			oLabelIn2->setStyleSheet(data->inputState(1) ? cgRedColor : "");
		else
			oLabelIn2->setStyleSheet(data->inputState(1) ? cgOrangeColor : "");
	}

	oLabelPowerOut->setText(trUtf8("СИЛОВОЙ ВЫХОД - ") + QString::number(data->outputState(WatchDataPacket::O_POWER) ? 1 : 0));
	oLabelPowerOut->setStyleSheet(data->outputState(WatchDataPacket::O_POWER) ? cgOrangeColor : "");
	oLabelAppendOut->setStyleSheet(data->outputState(WatchDataPacket::O_APPEND) ? cgOrangeColor : "");
	oLabelAppendOut->setText(trUtf8("Доп. выход"));

	oLabelEngine->setText(trUtf8("ДВИГАТЕЛЬ\n") + (data->engineIsWoork() ? trUtf8("РАБОТАЕТ") : trUtf8("НЕ РАБОТАЕТ")));
	oLabelEngine->setStyleSheet(data->engineIsWoork() ? cgOrangeColor : cgDefColor);

	QString style;
	switch (data->tempState())
	{
	case 0:
		if (oTempProtect)
			style = cgRedColor;
		text = trUtf8("ОБРЫВ");
		break;
	case 1:
		if (oTempProtect)
			style = cgGreenColor;
		text = trUtf8("НОРМА");
		break;
	case 2:
		if (oTempProtect)
			style = cgRedColor;
		text = trUtf8("ПЕРЕГРЕВ");
		break;
	case 3:
		if (oTempProtect)
			style = cgRedColor;
		text = trUtf8("ЗАМЫКАНИЕ");
		break;
	}
	oLabelTemp->setText(trUtf8("ТЕРМОДАТЧИК РТС\n") + text);
	oLabelTemp->setStyleSheet(style);

	style.clear();
	switch (data->tempRT100())
	{
	case 999:
		if (oRT100Protect)
			style = cgRedColor;
		text = trUtf8("ОБРЫВ");
		break;
	case -99:
		if (oRT100Protect)
			style = cgRedColor;
		text = trUtf8("ЗАМЫКАНИЕ");
		break;
	default:
		if (oRT100Protect)
			style = cgGreenColor;
		text = trUtf8("НОРМА");
		break;
	}
	oLabelRT100State->setText(trUtf8("ТЕРМОДАТЧИК РТ100\n") + text);
	oLabelRT100State->setStyleSheet(style);

	/*QString tempStyle;
	if (data->tempNom() <= 100)
		tempStyle = cgTempGreen;
	else if (data->tempNom() <= 110)
		tempStyle = cgTempOrange;
	else
		tempStyle = cgTempRed;

	oBarTemp->setValue(data->tempNom());
	oBarTemp->setStyleSheet(tempStyle);*/

	oTempPlot->updateData(data->tempRT100(), data->tempNom());

	double current[3] = { double(data->cur(P_A)), double(data->cur(P_B)), double(data->cur(P_C)) };
	double voltage[3] = { double(data->vol(P_A)), double(data->vol(P_B)), double(data->vol(P_C)) };
	oWatchPlot->updateData(current, voltage);

	oLabelWorkTime->setText(trUtf8("Наработка двигателя: ") + QString::number(data->workTime()) + trUtf8("ч."));
	oLabelTime->setText(QDateTime::fromTime_t(data->time()).toString("dd.MM.yyyy hh:mm:ss"));

	oBtnAppendOut->setText(trUtf8("Доп. выход\n") + (data->outputState(WatchDataPacket::O_APPEND) ? trUtf8("выкл") : trUtf8("вкл")));

	oBtnStop->setEnabled(oRemoteControl && data->outputState(WatchDataPacket::O_GENERAL));

	if (gDeviceVersion >= 80)
	{
		const WatchDataPacket80 *data80 = static_cast<const WatchDataPacket80*>(data);
		oLabelStartCounter->setText(trUtf8("Количества пусков двигателя: ") + QString::number(data80->startCount()));
	}
}
//======================================================================================
void TabWatch::updateConfig(const ConfigPacket *config)
{
	oInput1F = config->input1F();
	oInput2F = config->input2F();
	oWetProtect = config->wetnessProtect();

	oRemoteControl = config->remoteControl();

	oBtnForward->setEnabled(oRemoteControl);
	oBtnBack->setEnabled(oRemoteControl && config->powerOutputF() == 2);
	oBtnAppendOut->setEnabled(config->appendOutputF() == 4);

	oTempProtect = config->rtsProtect();
	oRT100Protect = config->rt100Protect();
}
//======================================================================================
void TabWatch::onDataEvent(const DataEvent *e)
{
	extern int gDeviceVersion;

	switch (e->type())
	{
	case DET_CONNECT:
		oWatchPlot->setFract(oMainWindow->deviceInfo()->curScale() == 10);
		oWatchPlot->restart();
		oLabelStartCounter->setVisible(gDeviceVersion >= 80);
		break;
	case DET_CONFIG:
		updateConfig(static_cast<const ConfigEvent*>(e)->config());
		break;
	case DET_GET_DATA:
		updateData(static_cast<const DataEventGet*>(e)->data());
		break;
	case DET_GET_PROTOCOLS:
		updateProtocol();
		break;
	default: break;
	}
}
//======================================================================================
void TabWatch::updateProtocol()
{
	oTableProtocol->updateProtocol();
}
//======================================================================================
void TabWatch::onBtnAppendOutClicked()
{
	oMainWindow->changeAppendOut();
}

void TabWatch::onBtnEngineCommandClicked()
{
	if (sender() == oBtnStop)
		oMainWindow->commandEngine(0);
	else if (sender() == oBtnForward)
		oMainWindow->commandEngine(1);
	else if (sender() == oBtnBack)
		oMainWindow->commandEngine(2);
}
//======================================================================================
void TabWatch::setPlotInterval(uint interval)
{
	oWatchPlot->setDuration(interval);
	oTempPlot->setDuration(interval);
}
